package com.iplay.实战java高并发程序设计.chapter2;

/**
 * @author dangwu
 * @since 2021/4/30 5:49 下午
 * <p>
 * 用好synchronized关键字，需要知道它的三种用法：
 * 1.指定加锁对象：对给定对象加锁，进入同步代码前需要获得给定对象的锁
 * 2.直接作用于实例方法：相当于对当前实例加锁，进入同步代码前需要获得当前实例的锁
 * 3.直接作用于静态方法：相当于对当前类加锁，进入同步代码前需要获得当前类的锁
 * 以下是三种写法
 * <p>
 * 方法一 指定加锁对象：
 */

/**
 * 方法一 指定加锁对象：
 */
//public class SynchronizedExplore implements Runnable{
//    static SynchronizedExplore instance = new SynchronizedExplore();
//    static int n = 0;
//    @Override
//    public void run() {
//        for (int i = 0; i < 10000000; i++) {
//            synchronized (instance){
//                n++;
//            }
//        }
//    }
//
//    public static void main(String[] args) throws InterruptedException {
//        Thread t1 = new Thread(new SynchronizedExplore());
//        Thread t2 = new Thread(new SynchronizedExplore());
//        t1.start();
//        t2.start();
//        t1.join();
//        t2.join();
//        System.out.println(n);
//    }
//}

/**
 * 给实例对象加锁：该写法与上面是等价的，但是需要注意：线程里面的参数对象必须是该类的同一个实例对象，
 * 如果是不同的实例对象，加是就是不同实例对象的锁，那么锁就等于没有加上
 */
public class SynchronizedExplore implements Runnable {
    //1.该处写法，与在main中创建一个对象是效果等同
    static SynchronizedExplore instance = new SynchronizedExplore();
    static int n = 0;

    private synchronized void increase() {
        n++;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10000000; i++) {
            increase();
        }
    }

    public static void main(String[] args) throws InterruptedException {
// 2.       SynchronizedExplore instance = new SynchronizedExplore();
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(n);
    }
}
/**
 * 给类加锁：给类加锁，那么线程中的参数对象可以是类的任意实例对象
 */
//public class SynchronizedExplore implements Runnable {
//    static int n = 0;
//
//    private static synchronized void increase(){
//        n++;
//    }
//
//    @Override
//    public  void run() {
//        for (int i = 0; i < 10000000; i++) {
//            increase();
//        }
//    }
//
//    public static void main(String[] args) throws InterruptedException {
//        Thread t1 = new Thread(new SynchronizedExplore());
//        Thread t2 = new Thread(new SynchronizedExplore());
//        t1.start();
//        t2.start();
//        t1.join();
//        t2.join();
//        System.out.println(n);
//    }
//}